/**
 * Copyright (C) 2010 altuure <altuure [AT] gmail [DOT] com> http://www.altuure.com/projects/yagdao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.altuure.yagdao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * DAO meta class for paging and sorting.
 * @author altuure
 */
public class YPage extends YLimit implements Serializable {

    /**
     * serialization key.
     */
    private static final long serialVersionUID = 1L;
    /**
     * order sort list.
     */
    private List<YOrder> orders = new ArrayList<YOrder>(2);

    /**
     * dao page serialization constructor.
     */
    public YPage() {
        super();
    }

    /**
     * dao page serialization constructor.
     * @param limit limits
     */
    public static YPage copy(YLimit limit) {
        if (limit == null)
            return new YPage();
        else
            return new YPage(limit.firstResult, limit.pageSize);
    }

    /**
     * order by given property asc.
     * @param orderBy property asc.
     */
    public YPage(String orderBy) {
        this(orderBy, true, NOT_ASSIGNED, NOT_ASSIGNED);
    }

    /**
     * order by given property.
     * @param orderBy property .
     * @param ascending is asc
     */
    public YPage(String orderBy, boolean ascending) {
        this(orderBy, ascending, NOT_ASSIGNED, NOT_ASSIGNED);
    }

    /**
     * dao page.
     * @param orderBy order property
     * @param ascending asc
     * @param firstResult first result index
     * @param pageSize result size
     */
    public YPage(String orderBy, boolean ascending, int firstResult, int pageSize) {
        super(firstResult, pageSize);
        if (orderBy != null)
            orders.add(new YOrder(orderBy, (ascending) ? YOrder.Sort.ASC : YOrder.Sort.DESC));
    }

    /**
     * limit result with given properties.
     * @param firstResult first result index
     * @param pageSize page size
     */
    public YPage(int firstResult, int pageSize) {
        this(null, false, firstResult, pageSize);
    }

    /**
     * unlimited result size from given index.
     * @param firstResult first result index
     */
    public YPage(int firstResult) {
        this(null, false, firstResult, NOT_ASSIGNED);
    }

    /** is ordered.
     * @return is ordered*/
    public boolean isOrdered() {
        return orders != null && !orders.isEmpty();
    }

    /**
     * util method to add order.
     * @param orderBy order property.
     * @param ascending sort order.
     * @return this
     */
    public YPage addOrder(String orderBy, boolean ascending) {
        orders.add(new YOrder(orderBy, (ascending) ? YOrder.Sort.ASC : YOrder.Sort.DESC));
        return this;
    }

    /**
     * builder method to sort result set.
     * @param orderBy propery to sort
     * @param sort sort order
     * @return this
     */
    public YPage addOrder(String orderBy, YOrder.Sort sort) {

        orders.add(new YOrder(orderBy, sort));
        return this;
    }

    /**
     * list of orders.
     * @return orders
     */
    public List<YOrder> getOrders() {
        return orders;
    }

    /**
     * orders to set.
     * @param orders orders
     */
    public void setOrders(List<YOrder> orders) {
        this.orders = orders;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.altuure.yagdao.DAOLimit#hashCode()
     */
    @Override
    public int hashCode() {
        int result = super.hashCode();
        final int prime = 31;
        result = prime * result + ((orders == null) ? 0 : orders.hashCode());

        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.altuure.yagdao.DAOLimit#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof YPage))
            return false;
        YPage other = (YPage) obj;
        if (!super.equals(obj))
            return false;
        if (orders == null) {
            if (other.orders != null)
                return false;
        } else if (!orders.equals(other.orders))
            return false;

        return true;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.altuure.yagdao.DAOLimit#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("DAOPage [orders=");
        builder.append(orders);
        builder.append(", DAOLimit=");
        builder.append(super.toString());
        builder.append("]");
        return builder.toString();
    }

}
